package com.chandon.juc.thread_basic;

import com.chandon.juc.SleepThread;

import java.util.concurrent.locks.ReentrantLock;

/**
 * Thread.interrupt(); 设置中断标志
 * Thread.isInterrupted(); 中断标志是否标记
 * Thread.interrupted(); 返回中断标志状态，并重置为false
 * InterruptedException 被catch后重置中断标志
 *
 *
 * interrupt不会打断竞争锁的线程synchroized Lock.lock()
 * 但可以打断Lock.lockInterruptibly()
 *
 * @author Dong
 * @version 1.0
 * @date 2021-04-06 15:03
 */

public class T03_ThreadInterrupt {

    private static final Object o = new Object();

    public static void main(String[] args) {

//        interruptTest();
//        sleepWithInterrupt();
//        waitWithInterrupt();
//        joinWithInterrupt();
//        interruptWithSynchroized();
//        interruptWithReentrantLock();
//        interruptWithReentrantLockInterruptibly();

    }

    private static void interruptWithReentrantLockInterruptibly() {
        ReentrantLock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {

            System.out.println("t1开始竞争锁");
            try {
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t1获取了锁");

        });

        new Thread(() -> {

            lock.lock();
            System.out.println("t2 拿到了锁并睡10秒");
            SleepThread.sleep(10);
            lock.unlock();
            System.out.println("t2释放锁");

        }).start();

        SleepThread.sleep(1);
        t1.start();
        System.out.println("1----"+t1.isInterrupted());

        SleepThread.sleep(1);
        t1.interrupt();
        System.out.println("2----"+t1.isInterrupted());
    }


    private static void interruptWithReentrantLock() {
        ReentrantLock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {

            System.out.println("t1开始竞争锁");
            lock.lock();
            System.out.println("t1获取了锁");

        });

        new Thread(() -> {

            lock.lock();
            System.out.println("t2 拿到了锁并睡10秒");
            SleepThread.sleep(10);
            lock.unlock();
            System.out.println("t2释放锁");

        }).start();
        // 主线程sleep让t2先执行
        SleepThread.sleep(1);
        // t2拿到锁并开始sleep,t1开始执行
        t1.start();
        System.out.println("1----"+t1.isInterrupted());
        SleepThread.sleep(1);
        t1.interrupt();
        System.out.println("2----"+t1.isInterrupted());
    }

    private static void interruptWithSynchroized() {
        Thread t1 = new Thread(() -> {

            System.out.println("t1开始竞争锁");

            synchronized (o) {
                System.out.println("t1获取了锁");
            }
        });

        new Thread(() -> {

            synchronized (o) {
                System.out.println("t2 sleep start");
                SleepThread.sleep(10);
            }

        }).start();
        SleepThread.sleep(1);
        t1.start();
        System.out.println(t1.isInterrupted());
        SleepThread.sleep(1);
        t1.interrupt();
        System.out.println(t1.isInterrupted());
    }

    private static void joinWithInterrupt() {
        Thread t = new Thread(() -> {
            Thread.currentThread().interrupt();
            try {
                System.out.println("1." + Thread.currentThread().isInterrupted());
                Thread.currentThread().join();
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("2." + Thread.currentThread().isInterrupted());
            }

        });

        t.start();
    }

    private static void waitWithInterrupt() {
        Thread t = new Thread(() -> {

            synchronized (o) {
                System.out.println("获取了锁，wait");

                try {
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(Thread.currentThread().isInterrupted());
                }

            }
        });

        t.start();
        SleepThread.sleep(2);
        t.interrupt();
    }

    private static void sleepWithInterrupt() {
        Thread t = new Thread(() -> {

            System.out.println("开始sleep");
            // false
            System.out.println(Thread.currentThread().isInterrupted());
            try {
                Thread.sleep(3000);

                System.out.println(Thread.currentThread().isInterrupted());
            } catch (InterruptedException e) {
                System.out.println("interrupted !");
                System.out.println(Thread.currentThread().isInterrupted());
            }
        });

        t.start();
        SleepThread.sleep(2);
        t.interrupt();
    }

    private static void interruptTest() {
        Thread t = new Thread(() -> {
            while (true) {

                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("interrupted");
                    System.out.println(Thread.currentThread().isInterrupted());
                    Thread.interrupted();
                    System.out.println(Thread.currentThread().isInterrupted());
                    break;

                }
            }

        });
        t.start();
        SleepThread.sleep(10);
        System.out.println(t.isInterrupted());
        t.interrupt();
    }

}
